#include "../import/head.h"
#include "impl.h"
#include "../data_struct/head.h"
#include "../global/head.h"
#include "../helper_proc/head.h"
#include "../helper_net/head.h"
#include "../macro/head.h"
#include "../msg/head.h"

namespace xos_sgsj
{

    impl::impl()
    {
        g_pSysData->m_pImpl = this;
    }

    impl::~impl()
    {
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int impl::run( int argc, const char  * argv[] )
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = init();
        }

        if( 0 == ret )
        {
            ret = helper_run();
        }
        
        ret = term();

        return ret;
    }

    // 
    // notify thread to work
    // 
    int impl::notify( data * pData )
    {
        int ret = 0;

        data::LIST & d_list = g_pSysData->m_pPool->m_data_list;
        d_list.lock();
        d_list.push_back( pData );
        d_list.unlock();
        m_pEvent->set_event();

        return ret;
    }

    int impl::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = g_pSysData->m_os.m_pXos->create( xos::i_xos::XOS_OBJ_EVENT, ( void ** )&m_pEvent );
        }

        if( 0 == ret )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_nMsg = MSG_START_PROGRAM;
            notify( p );
            p = 0;
        }

        return ret;
    }

    int impl::term()
    {
        int ret = 0;

        if( m_pEvent )
        {
            m_pEvent->release();
            m_pEvent = 0;
        }

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int impl::helper_run()
    {
        int ret = 0;

        while( ( 0 == ret ) && !g_pSysData->m_bQuit )
        {
            m_pEvent->wait( xos::i_event::EVENT_WAIT_INFINITE );
            proc();
        }

        return ret;
    }

    int impl::proc()
    {
        int ret = 0;

        data::LIST & d_list = g_pSysData->m_pPool->m_data_list;
        bool bFinished = false;

        while( !bFinished )
        {
            data * pData = 0;
            d_list.lock();
            pData = d_list.front();
            if( pData )
            {
                d_list.pop_front();
            }
            d_list.unlock();
            if( !pData )
            {
                bFinished = true;
                continue;
            }
            helper_proc obj;
            obj.proc( pData );
            pData = 0;
        }

        return ret;
    }

} // xos
